package com.hrma.services.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hrma.dao.EmployeeMapper;
import com.hrma.dao.OvertimeApplicationMapper;
import com.hrma.dao.WorkScheduleMapper;
import com.hrma.entity.*;
import com.hrma.entity.exception.StateException;
import com.hrma.services.OvertimeApplicationService;
import com.hrma.utils.UserUtil;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class OvertimeApplicationImpl implements OvertimeApplicationService {
    private final OvertimeApplicationMapper overtimeApplicationMapper;
    private final EmployeeMapper employeeMapper;
    private final WorkScheduleMapper workScheduleMapper;

    public OvertimeApplicationImpl(OvertimeApplicationMapper overtimeApplicationMapper, EmployeeMapper employeeMapper, WorkScheduleMapper workScheduleMapper) {
        this.overtimeApplicationMapper = overtimeApplicationMapper;
        this.employeeMapper = employeeMapper;
        this.workScheduleMapper = workScheduleMapper;
    }

    @Override
    public Integer add(OvertimeApplication data) {
        //不是在一天内不行
        if(!isOneDay(data)){
            return 1;
        }

        //一天内,周末几点都行，工作日期间不能在本就工作的时间内申请加班
        Calendar cale = Calendar.getInstance();
        cale.setTime(data.getBeginTime());
        if (cale.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY && cale.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) {
            //申请加班时间是工作期间不能申请
            if(isWorkTime(data)){
                return 2;
            }
        }

        data.setEmployeeId(UserUtil.getUserId());
        overtimeApplicationMapper.add(data);
        return 3;
    }

    @Override
    public Integer update(OvertimeApplication data) {
        if(!overtimeApplicationMapper.exist(data.getId())){
            throw new RuntimeException("id字段不存在！");
        }
        if(overtimeApplicationMapper.getState(data.getId()) != 0){
            throw new StateException("当前申请状态不能进行修改！");
        }

        //不是在一天内不行
        if(!isOneDay(data)){
            return 1;
        }

        //一天内,周末几点都行，工作日期间不能在本就工作的时间内申请加班
        Calendar cale = Calendar.getInstance();
        cale.setTime(data.getBeginTime());
        if (cale.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY && cale.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) {
            //申请加班时间是工作期间不能申请
            if(isWorkTime(data)){
                return 2;
            }
        }
        overtimeApplicationMapper.update(data);
        return 3;
    }

    @Override
    public List<SelectResult> select() {
        return overtimeApplicationMapper.select();
    }

    @Override
    public Page<OvertimeApplicationVO> getList(OvertimeApplicationDTO data) {
        data.setState(0);
        PageHelper.startPage(data.getPageNum(),data.getPageSize());
        return overtimeApplicationMapper.getList(data);
    }

    @Override
    public Page<OvertimeApplicationVO> getPersonalList(OvertimeApplicationDTO data) {
        data.setState(0);
        data.setEmployeeId(UserUtil.getUserId());
        PageHelper.startPage(data.getPageNum(),data.getPageSize());
        return overtimeApplicationMapper.getList(data);
    }


    /**
     * 将数据库存的工作时间整数转成请假日的时间类型
     */
    public WorkSchedulePO toOvertimePO(WorkSchedule workSchedule, Date beginTime) {
        //创建结果存储对象
        WorkSchedulePO workSchedulePO = new WorkSchedulePO();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginTime);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        calendar.set(year, month, day, workSchedule.getAmBeginTimeHour(), workSchedule.getAmBeginTimeMin(), 0);
        workSchedulePO.setAmBeginTime(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getAmBeginWorkHour(), workSchedule.getAmBeginWorkMin(), 0);
        workSchedulePO.setAmBeginWork(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getAmEndTimeHour(), workSchedule.getAmEndTimeMin(), 0);
        workSchedulePO.setAmEndTime(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getMidBeginTimeHour(), workSchedule.getMidBeginTimeMin(), 0);
        workSchedulePO.setMidBeginTime(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getAmEndWorkHour(), workSchedule.getAmEndWorkMin(), 0);
        workSchedulePO.setAmEndWork(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getMidEndTimeHour(), workSchedule.getMidEndTimeMin(), 0);
        workSchedulePO.setMidEndTime(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getPmBeginTimeHour(), workSchedule.getPmBeginTimeMin(), 0);
        workSchedulePO.setPmBeginTime(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getPmBeginWorkHour(), workSchedule.getPmBeginWorkMin(), 0);
        workSchedulePO.setPmBeginWork(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getPmEndTimeHour(), workSchedule.getPmEndTimeMin(), 0);
        workSchedulePO.setPmEndTime(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getEmBeginTimeHour(), workSchedule.getEmBeginTimeMin(), 0);
        workSchedulePO.setEmBeginTime(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getPmEndWorkHour(), workSchedule.getPmEndWorkMin(), 0);
        workSchedulePO.setPmEndWork(calendar.getTime());
        calendar.set(year, month, day, workSchedule.getEmEndTimeHour(), workSchedule.getEmEndTimeMin(), 0);
        workSchedulePO.setEmEndTime(calendar.getTime());

        return workSchedulePO;
    }

    public boolean isOneDay(OvertimeApplication data){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(data.getBeginTime());
        int year1 = calendar.get(Calendar.YEAR);
        int month1 = calendar.get(Calendar.MONTH);
        int day1 = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.setTime(data.getEndTime());
        int year2 = calendar.get(Calendar.YEAR);
        int month2 = calendar.get(Calendar.MONTH);
        int day2 = calendar.get(Calendar.DAY_OF_MONTH);
        //不是在一天内
        if(year1 != year2 || month1 != month2 || day1 != day2){
            return false;
        }
        return true;
    }

    public boolean isWorkTime(OvertimeApplication data){
        //得到考勤时间表
        WorkSchedule workSchedule = workScheduleMapper.getTime();
        //将考勤时间表存储的整数转成时间类型
        WorkSchedulePO workSchedulePO = toOvertimePO(workSchedule,data.getBeginTime());
        //上午工作期间结束
        boolean amEnd = (data.getEndTime().getTime() >= workSchedulePO.getAmBeginWork().getTime() && data.getEndTime().getTime() <= workSchedulePO.getAmEndWork().getTime());
        //上午工作期间开始
        boolean amBegin = (data.getBeginTime().getTime() >= workSchedulePO.getAmBeginWork().getTime() && data.getBeginTime().getTime() <= workSchedulePO.getAmEndWork().getTime());
        //包括整个上午工作期间
        boolean amAll = (data.getBeginTime().getTime() <= workSchedulePO.getAmBeginWork().getTime() && data.getEndTime().getTime() >= workSchedulePO.getAmEndWork().getTime());
        //下午工作期间开始
        boolean pmBegin = (data.getBeginTime().getTime() >= workSchedulePO.getPmBeginWork().getTime() && data.getBeginTime().getTime() <= workSchedulePO.getPmEndWork().getTime());
        //下午工作期间结束
        boolean pmEnd = (data.getEndTime().getTime() >= workSchedulePO.getPmBeginWork().getTime() && data.getEndTime().getTime() <= workSchedulePO.getPmEndWork().getTime());
        //包括整个下午工作期间
        boolean pmAll = (data.getBeginTime().getTime() <= workSchedulePO.getPmEndWork().getTime() && data.getEndTime().getTime() >= workSchedulePO.getPmEndWork().getTime());
        //是工作期间
        if(amEnd || amBegin || amAll || pmBegin || pmEnd || pmAll){
            return true;
        }
        return false;
    }
}
